package oauth

import (
	"net/http"
	"strings"

	"github.com/88250/gulu"
)

// AuthDispatchCenter as auth center to dispatch auth request to corresponding implement
type AuthDispatchCenter struct {
	AuthEndpointMap map[string]AuthServerHandler
}

// LoginRedirectHandler redirect to different oauth page according AuthServerFlag
func (auc *AuthDispatchCenter) LoginRedirectHandler(w http.ResponseWriter, r *http.Request) {
	authServerFlag := r.URL.Query().Get(AuthServerFlag)
	if authServerFlag == "" {
		log.Errorf("[AuthDispatchCenter] [LoginRedirectHandler] authServerFlag is empty")
		http.Error(w, "Forbidden", http.StatusForbidden)
		return
	}
	frontSite := r.URL.Query().Get(RedirectFrontPageUrl)
	if frontSite == "" {
		log.Errorf("[AuthDispatchCenter] [LoginRedirectHandler] site is empty")
		http.Error(w, "Forbidden", http.StatusForbidden)
		return
	}

	if endpoint, ok := auc.AuthEndpointMap[strings.ToUpper(authServerFlag)]; ok {
		stateCode := gulu.Rand.String(16)
		stateCodeCache.Add(stateCode)
		endpoint.LoginRedirectHandler(w, r, stateCode, frontSite)
		return
	}

	log.Warnf("[AuthDispatchCenter] [LoginRedirectHandler] no auth server implement found, %s ,[site] %s",
		authServerFlag, frontSite)
	http.Error(w, "Forbidden", http.StatusForbidden)
}

func (auc *AuthDispatchCenter) LoginCallbackHandler_old(w http.ResponseWriter, r *http.Request) {

	flagAndCode := r.URL.Query().Get(AuthServerFlagAndStateCode)
	log.Debugf("[AuthDispatchCenter] [LoginCallbackHandler] flag and code:%s", flagAndCode)

	authServerFlag, stateCode, site := ReadAuthFlagAndState(flagAndCode)
	if authServerFlag == "" {
		log.Errorf("[AuthDispatchCenter] [LoginRedirectHandler] auth server flag is empty.")
		http.Error(w, "Forbidden", http.StatusForbidden)
		return
	}

	if !stateCodeCache.RemoveIfExists(stateCode) {
		log.Errorf("[AuthDispatchCenter] [LoginCallbackHandler] state code is illegal. state code:%s", stateCode)
		http.Error(w, "state code illegal", http.StatusBadRequest)
		return
	}

	if endpoint, ok := auc.AuthEndpointMap[strings.ToUpper(authServerFlag)]; ok {
		endpoint.LoginCallbackHandler(w, r, stateCode, site)
		return
	}

	log.Warnf("[AuthDispatchCenter] [LoginCallbackHandler] no auth server implement found, %s", authServerFlag)
	http.Error(w, "Forbidden", http.StatusForbidden)
}

func (auc *AuthDispatchCenter) LoginCallbackHandler(w http.ResponseWriter, r *http.Request) {

	// flagAndCode := r.URL.Query().Get(AuthServerFlagAndStateCode)
	// log.Debugf("[AuthDispatchCenter] [LoginCallbackHandler] flag and code:%s", flagAndCode)

	// authServerFlag, stateCode, site := ReadAuthFlagAndState(flagAndCode)
	// if authServerFlag == "" {
	// 	log.Errorf("[AuthDispatchCenter] [LoginRedirectHandler] auth server flag is empty.")
	// 	http.Error(w, "Forbidden", http.StatusForbidden)
	// 	return
	// }

	// if !stateCodeCache.RemoveIfExists(stateCode) {
	// 	log.Errorf("[AuthDispatchCenter] [LoginCallbackHandler] state code is illegal. state code:%s", stateCode)
	// 	http.Error(w, "state code illegal", http.StatusBadRequest)
	// 	return
	// }

	site := r.URL.Query().Get("site")

	if endpoint, ok := auc.AuthEndpointMap[strings.ToUpper("CHAINMAKER")]; ok {
		endpoint.LoginCallbackHandler(w, r, "", site)
		return
	}

	log.Warnf("[AuthDispatchCenter] [LoginCallbackHandler] no auth server implement found, %s", "CHAINMAKER")
	http.Error(w, "Forbidden", http.StatusForbidden)
}

func (auc *AuthDispatchCenter) ThirdPartLoginHandler(w http.ResponseWriter, r *http.Request) {

	authServerFlag := r.URL.Query().Get(AuthServerFlag)
	if authServerFlag == "" {
		log.Errorf("[AuthDispatchCenter] [ThirdPartLoginHandler] auth server flag is empty.")
		http.Error(w, "Forbidden", http.StatusForbidden)
		//http.Redirect(w, r, "/login", http.StatusFound)
		return
	}
	site := r.URL.Query().Get(RedirectFrontPageUrl)
	if site == "" {
		log.Errorf("[AuthDispatchCenter] [ThirdPartLoginHandler] auth site flag is empty.")
		http.Error(w, "Forbidden", http.StatusForbidden)
		//http.Redirect(w, r, "/login", http.StatusFound)
		return
	}

	if endpoint, ok := auc.AuthEndpointMap[strings.ToUpper(authServerFlag)]; ok {
		endpoint.ThirdPartLoginHandler(w, r, site)
		return
	}

	log.Warnf("[AuthDispatchCenter] [ThirdPartLoginHandler] no auth server implement found, %s", authServerFlag)
	http.Error(w, "Forbidden", http.StatusForbidden)
	//http.Redirect(w, r, "/login", http.StatusFound)
}
